home *** CD-ROM | disk | FTP | other *** search
/ Programmer Plus 2007 / Programmer-Plus-2007.iso / Programming / Report Writers / Crystal Repot 9.0 Full CD version / Setup.exe / SRC / HOARDDLL.ZIP / 3rdParty / hoard / libhoard-2.0.2 / malloc-test.c < prev    next >
Encoding:
C/C++ Source or Header  |  2000-02-10  |  13.3 KB  |  457 lines

  1. /* malloc-test.c
  2.  * by Wolfram Gloger 1995, 1996
  3.  *
  4.  * This program is provided `as is', there is no warranty.
  5.  */
  6.  
  7. #include <stdlib.h>
  8. #include <stdio.h>
  9. #include <unistd.h>
  10. #include <sys/types.h>
  11. #include <sys/time.h>
  12. #include <sys/resource.h>
  13. #include <malloc.h>
  14.  
  15. #ifndef MEMORY
  16. #define MEMORY          4000000l
  17. #endif
  18. #ifndef BINS_MAX
  19. #define BINS_MAX        32768
  20. #endif
  21. #define SBINS_MAX       1024
  22. #define SIZE            10000
  23. #define I_MAX           5000
  24. #ifndef I_AVERAGE
  25. #define I_AVERAGE       200
  26. #endif
  27. #define ACTIONS_MAX     50
  28. #ifndef SBRK_AVG
  29. #define SBRK_AVG        0
  30. #endif
  31. #ifndef MMAP_THRESH
  32. #define MMAP_THRESH 0
  33. #endif
  34. #ifndef TEST
  35. #define TEST 4 /* minimal testing */
  36. #endif
  37. #ifndef TEST_INC
  38. #define TEST_INC 2047
  39. #endif
  40. #if defined(__i386__) || defined(__sparc__) || defined(mips)
  41. #define PAGE_SIZE 4096
  42. #elif defined(__alpha__)
  43. #define PAGE_SIZE 8192
  44. #elif defined(__SVR4)
  45. #define PAGE_SIZE 8192
  46. #else
  47. #error "Define PAGE_SIZE !"
  48. #endif
  49. #define RANDOM(s)       (lran2(0) % (s))
  50.  
  51. /* All probabilities are parts in 1024. */
  52. #ifndef PROB_MEMALIGN
  53. #define PROB_MEMALIGN 3
  54. #endif
  55. #ifndef PROB_REALLOC
  56. #define PROB_REALLOC 70
  57. #endif
  58. #ifndef PROB_CALLOC
  59. #define PROB_CALLOC 30
  60. #endif
  61.  
  62. struct bin {
  63.         unsigned char *ptr;
  64.         unsigned long size;
  65. } m[BINS_MAX], sm[SBINS_MAX];
  66.  
  67. unsigned long size = SIZE, bins=0, sbins=0;
  68. unsigned long total_size=0, total_size_max=0;
  69. unsigned char *base_ptr;
  70. unsigned long base_save;
  71.  
  72. long
  73. #if __STDC__
  74. lran2(long seed)
  75. #else
  76. lran2(seed) long seed;
  77. #endif
  78. #define LRAN2_MAX       714025l /* constants for portable */
  79. #define IA                      1366l   /* random number generator */
  80. #define IC                      150889l /* (see Numerical Recipes p. 211) */
  81. {
  82.         static int first = 1;
  83.         static long x, y, v[97];
  84.         int j;
  85.  
  86.         if(seed || first) {
  87.                 first = 0;
  88.                 x = (IC - seed) % LRAN2_MAX;
  89.                 if(x < 0) x = -x;
  90.                 for(j=0; j<97; j++) {
  91.                         x = (IA*x + IC) % LRAN2_MAX;
  92.                         v[j] = x;
  93.                 }
  94.                 x = (IA*x + IC) % LRAN2_MAX;
  95.                 y = x;
  96.         }
  97.         j = y % 97;
  98.         y = v[j];
  99.         x = (IA*x + IC) % LRAN2_MAX;
  100.         v[j] = x;
  101.         return y;
  102. }
  103. #undef IA
  104. #undef IC
  105.  
  106. void
  107. #if __STDC__
  108. mem_init(unsigned char *ptr, unsigned long size)
  109. #else
  110. mem_init(ptr, size) unsigned char *ptr; unsigned long size;
  111. #endif
  112. {
  113.         unsigned long i, j;
  114.  
  115.         if(size == 0) return;
  116.         if(size > sizeof(unsigned long)) {
  117.                 /* Try the complete initial word. */
  118.                 *(unsigned long *)ptr = (unsigned long)ptr ^ size;
  119.                 i = TEST_INC;
  120.         } else
  121.                 i = 0;
  122.         for(; i<size; i+=TEST_INC) {
  123.                 j = (unsigned long)ptr ^ i;
  124.                 ptr[i] = ((j ^ (j>>8)) & 0xFF);
  125.         }
  126.         j = (unsigned long)ptr ^ (size-1);
  127.         ptr[size-1] = ((j ^ (j>>8)) & 0xFF);
  128. }
  129.  
  130. int
  131. #if __STDC__
  132. mem_check(unsigned char *ptr, unsigned long size)
  133. #else
  134. mem_check(ptr, size) unsigned char *ptr; unsigned long size;
  135. #endif
  136. {
  137.         unsigned long i, j;
  138.  
  139.         if(size == 0) return 0;
  140.         if(size > sizeof(unsigned long)) {
  141.                 if(*(unsigned long *)ptr != ((unsigned long)ptr ^ size)) return 1;
  142.                 i = TEST_INC;
  143.         } else
  144.                 i = 0;
  145.         for(; i<size; i+=TEST_INC) {
  146.                 j = (unsigned long)ptr ^ i;
  147.                 if(ptr[i] != ((j ^ (j>>8)) & 0xFF)) return 2;
  148.         }
  149.         j = (unsigned long)ptr ^ (size-1);
  150.         if(ptr[size-1] != ((j ^ (j>>8)) & 0xFF)) return 3;
  151.         return 0;
  152. }
  153.  
  154. long
  155. #if __STDC__
  156. random_size(long max)
  157. #else
  158. random_size(max) long max;
  159. #endif
  160. {
  161.         long r1, r2, r, max_pages;
  162.  
  163.         max_pages = max/PAGE_SIZE;
  164.         if(max_pages > 0) {
  165.                 r1 = RANDOM(1024);
  166.                 r2 = (r1 & 7)*4;
  167.                 if(r1 < 512) {
  168.                         /* small value near power of two */
  169.                         r = (1L << (r1 >> 6)) + r2;
  170.                 } else if(r1 < 512+20) {
  171.                         /* value near a multiple of the page size */
  172.                         r = (RANDOM(max_pages)+1)*PAGE_SIZE + r2 - 16;
  173.                         /*printf("r = %4lx\n", r);*/
  174.                 } else r = RANDOM(max) + 1;
  175.         } else r = RANDOM(max) + 1;
  176.         /*if(r <= 0) exit(-1);*/
  177.         return r;
  178. }
  179.  
  180. void
  181. #if __STDC__
  182. bin_alloc(struct bin *m)
  183. #else
  184. bin_alloc(m) struct bin *m;
  185. #endif
  186. {
  187.         long r, key;
  188.         unsigned long sz;
  189.  
  190. #if TEST > 0
  191.         if(mem_check(m->ptr, m->size)) {
  192.                 printf("memory corrupt at %p, size=%lu!\n", m->ptr, m->size);
  193.                 exit(1);
  194.         }
  195. #endif
  196.         total_size -= m->size;
  197.         r = RANDOM(1024);
  198.         if(r < PROB_MEMALIGN) {
  199.                 if(m->size > 0) free(m->ptr);
  200.                 m->size = random_size(size);
  201.                 m->ptr = (unsigned char *)memalign(4 << RANDOM(8), m->size);
  202.         } else if(r < (PROB_MEMALIGN + PROB_REALLOC)) {
  203.                 if(m->size == 0) {
  204. #ifndef __sparc__
  205.                         m->ptr = NULL;
  206. #else
  207.                         /* SunOS4 does not realloc() a NULL pointer */
  208.                         m->ptr = (unsigned char *)malloc(1);
  209. #endif
  210.                 }
  211. #if TEST > 2
  212.                 key = RANDOM(256);
  213.                 sz = m->size;
  214.                 for(r=0; r<sz; r++) m->ptr[r] = (r ^ key) & 0xFF;
  215. #endif
  216.                 m->size = random_size(size);
  217.                 /*printf("realloc %d\n", (int)m->size);*/
  218.                 m->ptr = (unsigned char *)realloc(m->ptr, m->size);
  219. #if TEST > 2
  220.                 if(m->size < sz) sz = m->size;
  221.                 for(r=0; r<sz; r++)
  222.                         if(m->ptr[r] != ((r ^ key) & 0xFF)) {
  223.                                 printf("realloc bug !\n");
  224.                                 exit(1);
  225.                         }
  226. #endif
  227.         } else if(r < (PROB_MEMALIGN + PROB_REALLOC + PROB_CALLOC)) {
  228.                 if(m->size > 0) free(m->ptr);
  229.                 m->size = random_size(size);
  230.                 m->ptr = (unsigned char *)calloc(m->size, 1);
  231. #if TEST > 2
  232.                 for(r=0; r<m->size; r++)
  233.                         if(m->ptr[r] != '\0') {
  234.                                 printf("calloc bug !\n");
  235.                                 exit(1);
  236.                         }
  237. #endif
  238.         } else { /* normal malloc call */
  239.                 if(m->size > 0) free(m->ptr);
  240.                 m->size = random_size(size);
  241.                 m->ptr = (unsigned char *)malloc(m->size);
  242.         }
  243.         if(!m->ptr) {
  244.                 printf("out of memory!\n");
  245.                 exit(1);
  246.         }
  247.         total_size += m->size;
  248.         if(total_size > total_size_max) total_size_max = total_size;
  249. #if TEST > 0
  250.         mem_init(m->ptr, m->size);
  251. #endif
  252.         if(m->ptr < base_ptr) {
  253. #ifdef VERBOSE
  254.                 printf("hmmm, allocating below brk...\n");
  255. #endif
  256.                 base_ptr = m->ptr;
  257.         }
  258. }
  259.  
  260. void
  261. #if __STDC__
  262. bin_free(struct bin *m)
  263. #else
  264. bin_free(m) struct bin *m;
  265. #endif
  266. {
  267.         if(m->size == 0) return;
  268. #if TEST > 0
  269.         if(mem_check(m->ptr, m->size)) {
  270.                 printf("memory corrupt!\n");
  271.                 exit(1);
  272.         }
  273. #endif
  274.         total_size -= m->size;
  275.         free(m->ptr);
  276.         m->size = 0;
  277. }
  278.  
  279. void
  280. bin_test()
  281. {
  282.         unsigned int b;
  283.  
  284.         for(b=0; b<bins; b++) {
  285.                 if(mem_check(m[b].ptr, m[b].size)) {
  286.                         printf("memory corrupt!\n");
  287.                         exit(1);
  288.                 }
  289.         }
  290.         for(b=0; b<sbins; b++) {
  291.                 if(mem_check(sm[b].ptr, sm[b].size)) {
  292.                         printf("memory corrupt!\n");
  293.                         exit(1);
  294.                 }
  295.         }
  296. }
  297.  
  298. void
  299. print_times()
  300. {
  301.         struct rusage ru;
  302.         long total_sec, total_usec;
  303.  
  304.         getrusage(RUSAGE_SELF, &ru);
  305.         printf(" u=%ld.%06ldsec",
  306.                    (long)ru.ru_utime.tv_sec, (long)ru.ru_utime.tv_usec);
  307.         printf(" s=%ld.%06ldsec",
  308.                    (long)ru.ru_stime.tv_sec, (long)ru.ru_stime.tv_usec);
  309.         total_usec = (long)ru.ru_utime.tv_usec + (long)ru.ru_stime.tv_usec;
  310.         total_sec = (long)ru.ru_utime.tv_sec + (long)ru.ru_stime.tv_sec;
  311.         if(total_usec >= 1000000) {
  312.                 total_usec -= 1000000;
  313.                 total_sec++;
  314.         }
  315.         printf(" t=%ld.%06ldsec", total_sec, total_usec);
  316. }
  317.  
  318. int
  319. #if __STDC__
  320. main(int argc, char *argv[])
  321. #else
  322. main(argc, argv) int argc; char *argv[];
  323. #endif
  324. {
  325.         int i, j, next_i, count, max=I_MAX, actions;
  326.         unsigned int b;
  327.         long sbrk_max, sum;
  328.         double sbrk_used_sum, total_size_sum;
  329.         void* dummy = 0;
  330.  
  331.         if(argc > 1) max = atoi(argv[1]);
  332.         if(argc > 2) size = atoi(argv[2]);
  333.         lran2((long)max ^ size);
  334.         bins = (MEMORY/size)*4;
  335.         if(bins > BINS_MAX) bins = BINS_MAX;
  336.         base_ptr = (unsigned char *)sbrk(0);
  337.         sum = (long)base_ptr % PAGE_SIZE;
  338.         if(sum > 0) {
  339.                 if((char *)sbrk((long)PAGE_SIZE - sum) == (char *)-1) exit(1);
  340.                 base_ptr += (long)PAGE_SIZE - sum;
  341.                 /*printf("base_ptr = %lx\n", (long)base_ptr);*/
  342.         }
  343.         /* attempt to fill up the region below the initial brk */
  344.         for(i=0; i<10000; i++) {
  345.                 dummy = malloc(1);
  346.                 if(dummy >= (void*)base_ptr) break;
  347.         }
  348.         free(dummy);
  349.         base_save = ((unsigned long)base_ptr >> 24) << 24;
  350. #if MMAP_THRESH > 0
  351.         if(!mallopt(-3, MMAP_THRESH)) printf("mallopt failed!\n");
  352.         if(!mallopt(-4, 200)) printf("mallopt failed!\n");
  353. #endif
  354. #ifdef VERBOSE
  355.         printf("# mmap_thresh=%d\n", MMAP_THRESH);
  356.         printf("# bins=%d max=%d size=%d\n", bins, max, size);
  357.         printf("# base=%lx\n", base_save);
  358. #endif
  359.         for(b=0; b<bins; b++) {
  360.                 if(RANDOM(2) == 0) bin_alloc(&m[b]);
  361.                 else m[b].size = 0;
  362.         }
  363.         sbrk_max = 0;
  364.         sbrk_used_sum = total_size_sum = 0.0;
  365.         for(i=next_i=count=0; i<=max;) {
  366. #if TEST > 1
  367.                 bin_test();
  368. #endif
  369. #ifdef MSTATS
  370.                 malloc_stats();
  371. #endif
  372.                 actions = RANDOM(ACTIONS_MAX);
  373.                 for(j=0; j<actions; j++) {
  374.                         b = RANDOM(bins);
  375.                         bin_free(&m[b]);
  376. #if TEST > 3
  377.                         bin_test();
  378. #endif
  379.                 }
  380.                 i += actions;
  381. #ifdef AFTER_FREE
  382.                 AFTER_FREE;
  383. #endif
  384. #if SBRK_AVG > 0
  385.                 if(sbins<SBINS_MAX && RANDOM(SBRK_AVG)==0) {
  386.                         /* throw in an explicit sbrk call */
  387.                         sm[sbins].size = RANDOM(10000)+1;
  388.                         sm[sbins].ptr = sbrk(sm[sbins].size);
  389.                         if(sbins>0 && sm[sbins].ptr==(sm[sbins-1].ptr+sm[sbins-1].size)) {
  390.                                 sm[sbins-1].size += sm[sbins].size;
  391.                                 sbins--;
  392.                         }
  393. #ifdef VERBOSE
  394.                         printf("sbrk #%d %p %ld\n", sbins, sm[sbins].ptr, sm[sbins].size);
  395. #endif
  396. #if TEST > 0
  397.                         mem_init(sm[sbins].ptr, sm[sbins].size);
  398. #endif
  399.                         sbins++;
  400.                 }
  401. #endif
  402.                 actions = RANDOM(ACTIONS_MAX);
  403.                 for(j=0; j<actions; j++) {
  404.                         b = RANDOM(bins);
  405.                         bin_alloc(&m[b]);
  406. #if TEST > 3
  407.                         bin_test();
  408. #endif
  409.                 }
  410.                 i += actions;
  411.                 if(i >= next_i) { /* gather statistics */
  412.                         count++;
  413.                         sum = (long)sbrk(0);
  414.                         if(sum > sbrk_max) sbrk_max = sum;
  415.                         sbrk_used_sum += sum;
  416.                         total_size_sum += (double)total_size;
  417. #ifdef VERBOSE
  418.                         printf("%8d %7lu\n", i, total_size);
  419. #endif
  420.                         next_i += I_AVERAGE;
  421.                 }
  422.         }
  423.  
  424.         /* Correct sbrk values. */
  425.         sbrk_max -= (long)base_ptr;
  426.         sbrk_used_sum -= (double)count*(long)base_ptr;
  427. #ifdef VERBOSE
  428.         printf("# initial brk: %lx\n", (long)base_ptr);
  429.         printf("# max. sbrk()'ed memory: %ld bytes\n", sbrk_max);
  430.         printf("# avg. sbrk()'ed memory: %ld bytes\n",
  431.                    (long)(sbrk_used_sum/count));
  432.         printf("# current size allocated: %ld bytes\n", total_size);
  433.         printf("# maximum size allocated: %ld bytes\n", total_size_max);
  434.         printf("# average size allocated: %.1f bytes\n", total_size_sum/count);
  435.         printf("# current heap waste: %.2f%%\n",
  436.                    (1.0 - (double)total_size_max/sbrk_max)*100.0);
  437.         printf("# average heap waste: %.2f%%\n",
  438.                    (1.0 - (double)total_size_sum/sbrk_used_sum)*100.0);
  439.         printf("# total sbrk calls performed: %d\n", sbins);
  440. #else
  441.         printf("size=%7ld waste=%7.3f%%", size,
  442.                    /* (1.0 - (double)total_size_max/sbrk_max)*100.0, */
  443.                    (1.0 - (double)total_size_sum/sbrk_used_sum)*100.0);
  444.         print_times();
  445.         printf("\n");
  446. #endif
  447.         return 0;
  448. }
  449.  
  450. /*
  451.  * Local variables:
  452.  * tab-width:4
  453.  * compile-command: "gcc -Wall malloc-test.c -o malloc-test"
  454.  * End:
  455.  */
  456.  
  457.